home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / fragrouter / libpcap-0.4 / pcap-snit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-26  |  7.1 KB  |  301 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * Modifications made to accommodate the new SunOS4.0 NIT facility by
  22.  * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989.
  23.  * This module now handles the STREAMS based NIT.
  24.  */
  25.  
  26. #ifndef lint
  27. static const char rcsid[] =
  28.     "@(#) $Header: /cvs/fragrouter/libpcap-0.4/pcap-snit.c,v 1.1.1.1 1999/05/03 04:06:44 dugsong Exp $ (LBL)";
  29. #endif
  30.  
  31. #include <sys/types.h>
  32. #include <sys/time.h>
  33. #include <sys/timeb.h>
  34. #include <sys/dir.h>
  35. #include <sys/fcntlcom.h>
  36. #include <sys/file.h>
  37. #include <sys/ioctl.h>
  38. #include <sys/socket.h>
  39. #include <sys/stropts.h>
  40.  
  41. #include <net/if.h>
  42. #include <net/nit.h>
  43. #include <net/nit_if.h>
  44. #include <net/nit_pf.h>
  45. #include <net/nit_buf.h>
  46.  
  47. #include <netinet/in.h>
  48. #include <netinet/in_systm.h>
  49. #include <netinet/ip.h>
  50. #include <netinet/if_ether.h>
  51. #include <netinet/ip_var.h>
  52. #include <netinet/udp.h>
  53. #include <netinet/udp_var.h>
  54. #include <netinet/tcp.h>
  55. #include <netinet/tcpip.h>
  56.  
  57. #include <ctype.h>
  58. #include <errno.h>
  59. #ifdef HAVE_MALLOC_H
  60. #include <malloc.h>
  61. #endif
  62. #include <stdio.h>
  63. #include <string.h>
  64. #include <unistd.h>
  65.  
  66. #include "pcap-int.h"
  67.  
  68. #include "gnuc.h"
  69. #ifdef HAVE_OS_PROTO_H
  70. #include "os-proto.h"
  71. #endif
  72.  
  73. /*
  74.  * The chunk size for NIT.  This is the amount of buffering
  75.  * done for read calls.
  76.  */
  77. #define CHUNKSIZE (2*1024)
  78.  
  79. /*
  80.  * The total buffer space used by NIT.
  81.  */
  82. #define BUFSPACE (4*CHUNKSIZE)
  83.  
  84. /* Forwards */
  85. static int nit_setflags(int, int, int, char *);
  86.  
  87. int
  88. pcap_stats(pcap_t *p, struct pcap_stat *ps)
  89. {
  90.  
  91.     *ps = p->md.stat;
  92.     return (0);
  93. }
  94.  
  95. int
  96. pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
  97. {
  98.     register int cc, n;
  99.     register struct bpf_insn *fcode = p->fcode.bf_insns;
  100.     register u_char *bp, *cp, *ep;
  101.     register struct nit_bufhdr *hdrp;
  102.     register struct nit_iftime *ntp;
  103.     register struct nit_iflen *nlp;
  104.     register struct nit_ifdrops *ndp;
  105.     register int caplen;
  106.  
  107.     cc = p->cc;
  108.     if (cc == 0) {
  109.         cc = read(p->fd, (char *)p->buffer, p->bufsize);
  110.         if (cc < 0) {
  111.             if (errno == EWOULDBLOCK)
  112.                 return (0);
  113.             sprintf(p->errbuf, "pcap_read: %s",
  114.                 pcap_strerror(errno));
  115.             return (-1);
  116.         }
  117.         bp = p->buffer;
  118.     } else
  119.         bp = p->bp;
  120.  
  121.     /*
  122.      * loop through each snapshot in the chunk
  123.      */
  124.     n = 0;
  125.     ep = bp + cc;
  126.     while (bp < ep) {
  127.         ++p->md.stat.ps_recv;
  128.         cp = bp;
  129.  
  130.         /* get past NIT buffer  */
  131.         hdrp = (struct nit_bufhdr *)cp;
  132.         cp += sizeof(*hdrp);
  133.  
  134.         /* get past NIT timer   */
  135.         ntp = (struct nit_iftime *)cp;
  136.         cp += sizeof(*ntp);
  137.  
  138.         ndp = (struct nit_ifdrops *)cp;
  139.         p->md.stat.ps_drop = ndp->nh_drops;
  140.         cp += sizeof *ndp;
  141.  
  142.         /* get past packet len  */
  143.         nlp = (struct nit_iflen *)cp;
  144.         cp += sizeof(*nlp);
  145.  
  146.         /* next snapshot        */
  147.         bp += hdrp->nhb_totlen;
  148.  
  149.         caplen = nlp->nh_pktlen;
  150.         if (caplen > p->snapshot)
  151.             caplen = p->snapshot;
  152.  
  153.         if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) {
  154.             struct pcap_pkthdr h;
  155.             h.ts = ntp->nh_timestamp;
  156.             h.len = nlp->nh_pktlen;
  157.             h.caplen = caplen;
  158.             (*callback)(user, &h, cp);
  159.             if (++n >= cnt && cnt >= 0) {
  160.                 p->cc = ep - bp;
  161.                 p->bp = bp;
  162.                 return (n);
  163.             }
  164.         }
  165.     }
  166.     p->cc = 0;
  167.     return (n);
  168. }
  169.  
  170. static int
  171. nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
  172. {
  173.     bpf_u_int32 flags;
  174.     struct strioctl si;
  175.     struct timeval timeout;
  176.  
  177.     si.ic_timout = INFTIM;
  178.     if (to_ms != 0) {
  179.         timeout.tv_sec = to_ms / 1000;
  180.         timeout.tv_usec = (to_ms * 1000) % 1000000;
  181.         si.ic_cmd = NIOCSTIME;
  182.         si.ic_len = sizeof(timeout);
  183.         si.ic_dp = (char *)&timeout;
  184.         if (ioctl(fd, I_STR, (char *)&si) < 0) {
  185.             sprintf(ebuf, "NIOCSTIME: %s", pcap_strerror(errno));
  186.             return (-1);
  187.         }
  188.     }
  189.     flags = NI_TIMESTAMP | NI_LEN | NI_DROPS;
  190.     if (promisc)
  191.         flags |= NI_PROMISC;
  192.     si.ic_cmd = NIOCSFLAGS;
  193.     si.ic_len = sizeof(flags);
  194.     si.ic_dp = (char *)&flags;
  195.     if (ioctl(fd, I_STR, (char *)&si) < 0) {
  196.         sprintf(ebuf, "NIOCSFLAGS: %s", pcap_strerror(errno));
  197.         return (-1);
  198.     }
  199.     return (0);
  200. }
  201.  
  202. pcap_t *
  203. pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
  204. {
  205.     struct strioctl si;        /* struct for ioctl() */
  206.     struct ifreq ifr;        /* interface request struct */
  207.     int chunksize = CHUNKSIZE;
  208.     int fd;
  209.     static char dev[] = "/dev/nit";
  210.     register pcap_t *p;
  211.  
  212.     p = (pcap_t *)malloc(sizeof(*p));
  213.     if (p == NULL) {
  214.         strcpy(ebuf, pcap_strerror(errno));
  215.         return (NULL);
  216.     }
  217.  
  218.     if (snaplen < 96)
  219.         /*
  220.          * NIT requires a snapshot length of at least 96.
  221.          */
  222.         snaplen = 96;
  223.  
  224.     bzero(p, sizeof(*p));
  225.     p->fd = fd = open(dev, O_RDONLY);
  226.     if (fd < 0) {
  227.         sprintf(ebuf, "%s: %s", dev, pcap_strerror(errno));
  228.         goto bad;
  229.     }
  230.  
  231.     /* arrange to get discrete messages from the STREAM and use NIT_BUF */
  232.     if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
  233.         sprintf(ebuf, "I_SRDOPT: %s", pcap_strerror(errno));
  234.         goto bad;
  235.     }
  236.     if (ioctl(fd, I_PUSH, "nbuf") < 0) {
  237.         sprintf(ebuf, "push nbuf: %s", pcap_strerror(errno));
  238.         goto bad;
  239.     }
  240.     /* set the chunksize */
  241.     si.ic_cmd = NIOCSCHUNK;
  242.     si.ic_timout = INFTIM;
  243.     si.ic_len = sizeof(chunksize);
  244.     si.ic_dp = (char *)&chunksize;
  245.     if (ioctl(fd, I_STR, (char *)&si) < 0) {
  246.         sprintf(ebuf, "NIOCSCHUNK: %s", pcap_strerror(errno));
  247.         goto bad;
  248.     }
  249.  
  250.     /* request the interface */
  251.     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  252.     ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
  253.     si.ic_cmd = NIOCBIND;
  254.     si.ic_len = sizeof(ifr);
  255.     si.ic_dp = (char *)𝔦
  256.     if (ioctl(fd, I_STR, (char *)&si) < 0) {
  257.         sprintf(ebuf, "NIOCBIND: %s: %s",
  258.             ifr.ifr_name, pcap_strerror(errno));
  259.         goto bad;
  260.     }
  261.  
  262.     /* set the snapshot length */
  263.     si.ic_cmd = NIOCSSNAP;
  264.     si.ic_len = sizeof(snaplen);
  265.     si.ic_dp = (char *)&snaplen;
  266.     if (ioctl(fd, I_STR, (char *)&si) < 0) {
  267.         sprintf(ebuf, "NIOCSSNAP: %s", pcap_strerror(errno));
  268.         goto bad;
  269.     }
  270.     p->snapshot = snaplen;
  271.     if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
  272.         goto bad;
  273.  
  274.     (void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
  275.     /*
  276.      * NIT supports only ethernets.
  277.      */
  278.     p->linktype = DLT_EN10MB;
  279.  
  280.     p->bufsize = BUFSPACE;
  281.     p->buffer = (u_char *)malloc(p->bufsize);
  282.     if (p->buffer == NULL) {
  283.         strcpy(ebuf, pcap_strerror(errno));
  284.         goto bad;
  285.     }
  286.     return (p);
  287.  bad:
  288.     if (fd >= 0)
  289.         close(fd);
  290.     free(p);
  291.     return (NULL);
  292. }
  293.  
  294. int
  295. pcap_setfilter(pcap_t *p, struct bpf_program *fp)
  296. {
  297.  
  298.     p->fcode = *fp;
  299.     return (0);
  300. }
  301.